#include "main.h"
#include "log.h"
#include "server.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
// 全局服务端实例指针，用于信号处理
static Server* g_server = NULL;

// 信号处理函数，用于优雅退出
static void signal_handler(int signum) {
    if (signum == SIGINT || signum == SIGTERM) {
         log_info("收到退出信号，正在关闭服务端...");
        if (g_server != NULL) {
            server_destroy(g_server);
            g_server = NULL;
        }
        log_close();
        exit(EXIT_SUCCESS);
    }
}

// 注册信号处理
static void register_signals() {
    struct sigaction sa;
    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = signal_handler;
    
    // 注册SIGINT(ctrl+c)和SIGTERM信号处理
    if (sigaction(SIGINT, &sa, NULL) == -1 || 
        sigaction(SIGTERM, &sa, NULL) == -1) {
        perror("注册信号处理失败");
        exit(EXIT_FAILURE);
    }
    
    // 忽略SIGPIPE信号(避免写入已关闭的套接字导致程序退出)
    sa.sa_handler = SIG_IGN;
    if (sigaction(SIGPIPE, &sa, NULL) == -1) {
        perror("忽略SIGPIPE信号失败");
        exit(EXIT_FAILURE);
    }
}

// 初始化默认配置
void init_default_config(ServerConfig* config) {
    if (config == NULL) return;
    
    config->port = 8080;
    config->config_file = NULL;
    config->log_file = "server.log";
    config->max_connections = 100;
    config->daemon_mode = false;
    config->timeout = 300;
}

// 解析命令行参数
int parse_command_line(int argc, char* argv[], ServerConfig* config) {
    int opt;
    const char* short_options = "p:c:l:m:dt:h";
    const struct option long_options[] = {
        {"port",        required_argument, NULL, 'p'},
        {"config",      required_argument, NULL, 'c'},
        {"log",         required_argument, NULL, 'l'},
        {"max-conn",    required_argument, NULL, 'm'},
        {"daemon",      no_argument,       NULL, 'd'},
        {"timeout",     required_argument, NULL, 't'},
        {"help",        no_argument,       NULL, 'h'},
        {NULL,          0,                 NULL, 0}
    };

    while ((opt = getopt_long(argc, argv, short_options, long_options, NULL)) != -1) {
        switch (opt) {
            case 'p':
                config->port = (uint16_t)atoi(optarg);
                if (config->port < 1 || config->port > 65535) {
                    fprintf(stderr, "无效的端口号: %s\n", optarg);
                    return -1;
                }
                break;
            case 'c':
                config->config_file = optarg;
                break;
            case 'l':
                config->log_file = optarg;
                break;
            case 'm':
                config->max_connections = atoi(optarg);
                if (config->max_connections <= 0) {
                    fprintf(stderr, "无效的最大连接数: %s\n", optarg);
                    return -1;
                }
                break;
            case 'd':
                config->daemon_mode = true;
                break;
            case 't':
                config->timeout = atoi(optarg);
                if (config->timeout <= 0) {
                    fprintf(stderr, "无效的超时时间: %s\n", optarg);
                    return -1;
                }
                break;
            case 'h':
                printf("使用方法: %s [选项...]\n", argv[0]);
                printf("  -p, --port <端口>      服务端监听端口(默认: 8080)\n");
                printf("  -c, --config <文件>    配置文件路径\n");
                printf("  -l, --log <文件>       日志文件路径(默认: server.log)\n");
                printf("  -m, --max-conn <数>    最大连接数(默认: 100)\n");
                printf("  -d, --daemon           以守护进程模式运行\n");
                printf("  -t, --timeout <秒>     连接超时时间(默认: 300)\n");
                printf("  -h, --help             显示帮助信息\n");
                exit(EXIT_SUCCESS);
            default:
                fprintf(stderr, "使用 -h 或 --help 查看帮助信息\n");
                return -1;
        }
    }

    return 0;
}

// 从配置文件加载配置(简化实现)
int load_config_file(const char* filename, ServerConfig* config) {
    if (filename == NULL || config == NULL) return -1;
    
    FILE* file = fopen(filename, "r");
    if (file == NULL) {
        perror("打开配置文件失败");
        return -1;
    }

    char line[256];
    while (fgets(line, sizeof(line), file) != NULL) {
        // 跳过注释和空行
        if (line[0] == '#' || line[0] == '\n' || line[0] == ' ') continue;
        
        // 解析键值对(格式: key=value)
        char* key = strtok(line, "=");
        char* value = strtok(NULL, "\r\n");
        
        if (key && value) {
            if (strcmp(key, "port") == 0) {
                config->port = (uint16_t)atoi(value);
            } else if (strcmp(key, "log_file") == 0) {
                config->log_file = strdup(value);
            } else if (strcmp(key, "max_connections") == 0) {
                config->max_connections = atoi(value);
            } else if (strcmp(key, "daemon_mode") == 0) {
                config->daemon_mode = (strcmp(value, "true") == 0);
            } else if (strcmp(key, "timeout") == 0) {
                config->timeout = atoi(value);
            }
        }
    }

    fclose(file);
    return 0;
}

// 显示配置信息
void print_config(const ServerConfig* config) {
    if (config == NULL) return;
    
    log_info("服务端配置信息:");
    log_info("  监听端口: %d", config->port);
    log_info("  配置文件: %s", config->config_file ? config->config_file : "未指定");
    log_info("  日志文件: %s", config->log_file);
    log_info("  最大连接数: %d", config->max_connections);
    log_info("  守护进程模式: %s", config->daemon_mode ? "开启" : "关闭");
    log_info("  连接超时时间: %d秒", config->timeout);
}

// 切换到守护进程模式
static int become_daemon() {
    pid_t pid = fork();
    if (pid < 0) return -1;
    if (pid > 0) exit(EXIT_SUCCESS); // 退出父进程
    
    // 创建新的会话
    if (setsid() < 0) return -1;
    
    // 再次fork，避免成为会话首进程
    pid = fork();
    if (pid < 0) return -1;
    if (pid > 0) exit(EXIT_SUCCESS);
    
    // 改变工作目录
    if (chdir("/") < 0) return -1;
    
    // 关闭所有文件描述符
    for (int i = 0; i < 1024; i++) {
        close(i);
    }
    
    // 重定向标准输入、输出、错误到/dev/null
    open("/dev/null", O_RDWR);
    dup(0);
    dup(0);
    
    return 0;
}

// 程序入口
int main(int argc, char* argv[]) {
    ServerConfig config;
   

    // 初始化默认配置
    init_default_config(&config);
    
    // 解析命令行参数
    if (parse_command_line(argc, argv, &config) != 0) {
        return EXIT_FAILURE;
    }
    
    // 加载配置文件(如果指定)
    if (config.config_file != NULL) {
        if (load_config_file(config.config_file, &config) != 0) {
            fprintf(stderr, "加载配置文件失败: %s\n", config.config_file);
            return EXIT_FAILURE;
        }
    }
    
    // 初始化日志系统
    if (log_init(config.log_file) != 0) {
        fprintf(stderr, "初始化日志系统失败\n");
        return EXIT_FAILURE;
    }
    
    // 显示配置信息
    print_config(&config);
    
    // 切换到守护进程模式(如果需要)
    if (config.daemon_mode) {
        log_info("切换到守护进程模式...");
        if (become_daemon() != 0) {
            log_error("切换到守护进程模式失败");
            log_close();
            return EXIT_FAILURE;
        }
    }
    
    // 注册信号处理
    register_signals();
    
    // 初始化并启动服务端
    log_info("正在启动服务端...");
    g_server = server_init(config.port);
    if (g_server == NULL) {
        log_error("服务端初始化失败");
        log_close();
        return EXIT_FAILURE;
    }
    
    log_info("服务端启动成功，监听端口: %d", config.port);
    server_start(g_server);
    
    // 正常退出
    server_destroy(g_server);
    log_info("服务端已正常关闭");
    log_close();
    return EXIT_SUCCESS;
}

